package org.mspring.mlog.imports;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.mspring.mlog.common.ArticleImage;
import org.mspring.mlog.entity.Article;
import org.mspring.mlog.entity.Category;
import org.mspring.mlog.entity.Comment;
import org.mspring.mlog.entity.User;
import org.mspring.mlog.entity.em.ArticleStatus;
import org.mspring.mlog.entity.em.CommentStatus;
import org.mspring.mlog.service.ArticleService;
import org.mspring.mlog.service.ArticleTagService;
import org.mspring.mlog.service.CategoryService;
import org.mspring.mlog.service.CommentService;
import org.mspring.mlog.service.TagService;
import org.mspring.nbee.common.utils.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * 数据迁移服务
 *
 * @author Gao Youbo
 * @since 2015-01-04 16:24
 */
@Service
public class ImportService {

    private CategoryService categoryService;
    private TagService tagService;
    private ArticleService articleService;
    private ArticleTagService articleTagService;
    private CommentService commentService;

    private static User user = null;

    static {
        user = new User();
        user.setId(1L);
        user.setNickname("雾非雾的情思");
    }

    @Transactional
    public void importCategory() {
        getJdbcTemplate().query("select * from t_catalog", new RowCallbackHandler() {
            @Override
            public void processRow(ResultSet rs) throws SQLException {
                Category category = new Category();
                category.setId(rs.getLong("id"));
                category.setName(rs.getString("name"));
                category.setCreateTime(rs.getDate("create_time"));
                category.setCreateUserName("雾非雾的情思");
                category.setCreateUser(1L);
                category.setUpdateTime(rs.getDate("create_time"));
                category.setUpdateUserName("雾非雾的情思");
                category.setUpdateUser(1L);
                category.setDeleted(false);
                categoryService.insert(category);
            }
        });
    }

    @Transactional
    public void importArticle() {
        getJdbcTemplate().query("select * from t_post order by id desc", new RowCallbackHandler() {
            @Override
            public void processRow(ResultSet rs) throws SQLException {
                try {
                    String postStatus = rs.getString("post_status");
                    int status = ArticleStatus.NORMAL;
                    if (StringUtils.equals(postStatus, "draft")) {
                        return;
                    }
                    if (StringUtils.equals(postStatus, "trash")) {
                        status = ArticleStatus.DELEtED;
                    }
                    long postId = rs.getLong("id");
                    long catalog = getPostCategory(postId);
                    List<String> tags = listTags(postId);
                    List<ArticleImage> articleImages = getArticleImages(postId);
                    Article article = new Article();
                    article.setId(postId);
                    article.setCategory(catalog);
                    article.setTitle(rs.getString("title"));
                    article.setContent(rs.getString("content"));
                    article.setViewCount(rs.getInt("views"));
                    article.setStatus(status);
                    if (CollectionUtils.isNotEmpty(articleImages)) {
                        article.setImageList(JSON.toJSONString(articleImages));
                    }
                    article.setCreateTime(rs.getDate("create_time"));
                    article.setCreateUserName("雾非雾的情思");
                    article.setCreateUser(1L);
                    article.setUpdateTime(rs.getDate("create_time"));
                    article.setUpdateUserName("雾非雾的情思");
                    article.setUpdateUser(1L);
                    articleService.createArticle(article, tags, user);
                    importComment(postId);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 导入评论
     */
    @Transactional
    public void importComment(final long articleId) {
        getJdbcTemplate().query("select * from t_comment where status = 'approved' and post = " + articleId, new RowCallbackHandler() {
            @Override
            public void processRow(ResultSet rs) throws SQLException {
                Comment comment = new Comment();
                comment.setId(rs.getLong("id"));
                comment.setArticleId(articleId);
                comment.setReplyId(rs.getLong("parent"));
                comment.setStatus(CommentStatus.APPROVED);
                comment.setAuthorName(rs.getString("author"));
                comment.setAuthorEmail(rs.getString("email"));
                comment.setAuthorUrl(rs.getString("url"));
                comment.setContent(rs.getString("content"));
                comment.setIp(rs.getString("post_ip"));
                comment.setAgent(rs.getString("agent"));
                comment.setCreateTime(rs.getDate("create_time"));
                commentService.insert(comment);
            }
        });
    }


    /**
     * 列出文章标签
     *
     * @param postId
     * @return
     */
    private List<String> listTags(long postId) {
        return getJdbcTemplate().query("select distinct t.* from t_tag t, t_post_tag pt where t.id = pt.tag_id and pt.post_id = " + postId, new RowMapper<String>() {
            @Override
            public String mapRow(ResultSet rs, int rowNum) throws SQLException {
                return rs.getString("name");
            }
        });
    }

    /**
     * 获取文章的分类
     *
     * @param postId
     * @return
     */
    private long getPostCategory(long postId) {
        return getJdbcTemplate().query("select distinct pc.* from t_catalog c, t_post_catalog pc where c.id = pc.catalog_id and pc.post_id = " + postId, new ResultSetExtractor<Long>() {
            @Override
            public Long extractData(ResultSet rs) throws SQLException, DataAccessException {
                if (rs.next()) {
                    return rs.getLong("catalog_id");
                }
                return 8L;
            }
        });
    }


    /**
     * 获取文章对应的图片
     *
     * @param postId
     * @return
     */
    private List<ArticleImage> getArticleImages(long postId) {
        return getJdbcTemplate().query("select * from t_attachment where foreign_key = " + postId, new RowMapper<ArticleImage>() {
            @Override
            public ArticleImage mapRow(ResultSet rs, int rowNum) throws SQLException {
                String url = rs.getString("url");
                String key = StringUtils.substringAfter(url, "http://file.mspring.org/");
                ArticleImage image = new ArticleImage();
                image.setUrl(url);
                image.setKey(key);
                return image;
            }
        });
    }

    private JdbcTemplate jdbcTemplate;

    private JdbcTemplate getJdbcTemplate() {
        if (jdbcTemplate == null) {
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/mlog?useUnicode=true&characterEncoding=utf8");
            dataSource.setUsername("root");
            dataSource.setPassword("gaoyoubo");
            jdbcTemplate = new JdbcTemplate();
            jdbcTemplate.setDataSource(dataSource);
        }
        return jdbcTemplate;
    }

    @Autowired
    public void setCategoryService(CategoryService categoryService) {
        this.categoryService = categoryService;
    }

    @Autowired
    public void setTagService(TagService tagService) {
        this.tagService = tagService;
    }

    @Autowired
    public void setArticleService(ArticleService articleService) {
        this.articleService = articleService;
    }

    @Autowired
    public void setArticleTagService(ArticleTagService articleTagService) {
        this.articleTagService = articleTagService;
    }

    @Autowired
    public void setCommentService(CommentService commentService) {
        this.commentService = commentService;
    }
}
